﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MultiCola
{
    /**
     * Esta clase maneja un arreglo de colas, utilizando las colas de System.Collections.Generic.
     */
    public class MultiCola<T>{

        private Queue<T>[] _colas;

        /*
         *El parametro 'colas' debe ser superior a 0. 
         */
        public MultiCola(int colas)
        {
            _colas = new Queue<T>[colas];

            for (int i = 0; i < colas; i++)
            {
                _colas[i] = new Queue<T>();
            }
        }

        public int colas()
        {
            return _colas.Count();
        }

        public int size()
        {
            int salida = 0;

            foreach (Queue<T> colaTemporal in _colas)
            {
                salida += colaTemporal.Count;
            }

            return salida;
        }

        public int size(int cola)
        {
            return _colas[cola-1].Count;
        }

        public Boolean isEmpty()
        {
            bool salida = true;
            foreach (Queue<T> colaTemporal in _colas)
            {
                if (colaTemporal.Count != 0)
                {
                    salida = false;
                }
            }
            return salida;
        }

        public Boolean isEmpty(int cola)
        {
            bool salida = true;
            if (_colas[cola-1].Count != 0)
            {
                salida = false;
            }
            return salida;
        }

        public Boolean enQueue(T objeto, int cola)
        {
            try
            {
                _colas[cola-1].Enqueue(objeto);
                return true;
            }
            catch (Exception e)
            {
                return false;
            }
        }

        public T deQueue(int cola)
        {
            try
            {
                T objeto = _colas[cola-1].Dequeue();
                return objeto;
            }
            catch (InvalidOperationException e) {
                throw e;
            }
        }

        public T peek (int cola)
        {
            try
            {
                T objeto = _colas[cola-1].Peek();
                return objeto;
            }
            catch (InvalidOperationException e) {
                throw e;
            }
        }

        /*
         *int cola: es la cola de la cual se le quiere cambiar la prioridad al primer objeto.         
         */
        public Boolean swap(int origen,int destino)
        {
            bool salida = true;
            try{
            T temporal = _colas[origen-1].Dequeue();
            _colas[destino].Enqueue(temporal);
            }catch(Exception e){
                salida = false;
            }
            return salida;

        }
        
    }

}
